package pers.cj.pdos.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.mapper.*;
import pers.cj.pdos.service.IBorrowInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.cj.pdos.utils.PdosUtils;
import pers.cj.pdos.utils.Utils;
import pers.cj.pdos.utils.UuidUtils;
import pers.cj.pdos.vo.BorrowInGoodsVo;
import pers.cj.pdos.vo.BorrowInVo;
import pers.cj.pdos.vo.InGoodsGoodsVo;
import pers.cj.pdos.vo.InGoodsVo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 借入单后处于待入库状态，归还状态为未归还状态，等进行进货或者归还后，则规范状态为已归还。 服务实现类
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Service
public class BorrowInServiceImpl extends ServiceImpl<BorrowInMapper, BorrowIn> implements IBorrowInService {
    @Autowired
    BorrowInMapper borrowInMapper;
    @Autowired
    BorrowInGoodsMapper borrowInGoodsMapper;
    @Autowired
    GoodsSnMapper goodsSnMapper;
    @Autowired
    GoodsSnLogMapper goodsSnLogMapper;
    @Autowired
    GoodsStockMapper goodsStockMapper;
    @Autowired
    HouseWaitInMapper houseWaitInMapper;
    @Autowired
    HouseWaitInGoodsMapper houseWaitInGoodsMapper;

    @Override
    public boolean checkNo(String no, String companyId) {
        return borrowInMapper.selectCount(new QueryWrapper<BorrowIn>().eq("company_id",companyId).eq("no",no)) > 0;
    }

    @Override
    public boolean checkClose(BorrowIn borrowIn) {
        return borrowInMapper.selectCount(new QueryWrapper<BorrowIn>().eq("id",borrowIn.getId()).eq("close",true))  > 0;
    }

    @Override
    public void insert(BusinessSet businessSet, BorrowIn borrowIn, List<BorrowInGoods> borrowInGoodsList, List<GoodsSn> goodsSnList, List<GoodsSnLog> goodsSnLogList) {
        borrowInMapper.insert(borrowIn);
        borrowInGoodsMapper.insertBatch(borrowInGoodsList);

        BorrowInVo borrowInVo = borrowInMapper.getVoById(borrowIn.getId());
        if (!PdosUtils.houseInOut(businessSet)) {
            //未启用出入库管理，直接添加库存
            processGoodsStock(1, borrowInVo);
            if (!Utils.isEmpty(goodsSnList)) {
                goodsSnMapper.insertBatch(goodsSnList);
                goodsSnLogMapper.insertBatch(goodsSnLogList);
            }
        } else {
            //启用库存管理，则添加待入库单数据
            processHouseWaitIn(1, borrowInVo);
        }
    }

    @Override
    public void close(BorrowIn borrowIn, BusinessSet businessSet) {
        BorrowInVo borrowInVo = borrowInMapper.getVoById(borrowIn.getId());

        //直接入库的进货单，则需要去除相应的库存和sn。
        if (borrowInVo.getStatus() == 1) {
            processGoodsStock(2, borrowInVo);
            //关闭进货单需要sn号需要处与出库状态
            List<GoodsSn> list = PdosUtils.genGoodsSnList(borrowInVo.getBorrowInGoodsVoList());
            if (!Utils.isEmpty(list)) {
                goodsSnMapper.outByList(borrowInVo.getHouseId(), list);
            }
        } else {
            processHouseWaitIn(2,borrowInVo);
        }

        BorrowIn temp = new BorrowIn();
        temp.setId(borrowInVo.getId());
        temp.setClose(true);
        borrowInMapper.updateById(temp);
    }

    @Override
    public List<BorrowInVo> listVo(String companyId,
                                   Integer page,
                                   Integer limit,
                                   Boolean close,
                                   String search,
                                   String no,
                                   String goodsName,
                                   String remark,
                                   String provider,
                                   Date makeTime1,
                                   Date makeTime2,
                                   String storeId,
                                   String userStoreId,
                                   String userId,
                                   Date date1,
                                   Date date2,
                                   String houseId,
                                   String makeUserId,
                                   Integer inStatus) {
        return borrowInMapper.listVo(companyId,
                Utils.genPage(page,limit),
                limit,
                null,
                close,
                search,
                no,
                goodsName,
                remark,
                provider,
                makeTime1,
                makeTime2,
                storeId,
                userStoreId,
                userId,
                date1,
                date2,
                houseId,
                makeUserId,
                inStatus);
    }

    @Override
    public long count(String companyId,
                      Boolean close,
                      String search,
                      String no,
                      String goodsName,
                      String remark,
                      String provider,
                      Date makeTime1,
                      Date makeTime2,
                      String storeId,
                      String userStoreId,
                      String userId,
                      Date date1,
                      Date date2,
                      String houseId,
                      String makeUserId,
                      Integer inStatus) {
        return borrowInMapper.count(companyId,
                null,
                close,
                search,
                no,
                goodsName,
                remark,
                provider,
                makeTime1,
                makeTime2,
                storeId,
                userStoreId,
                userId,
                date1,
                date2,
                houseId,
                makeUserId,
                inStatus);
    }

    @Override
    public List<BorrowInVo> listVoByIds(List<String> ids) {
        return borrowInMapper.listVoByIds(ids);
    }

    @Override
    public BorrowInVo getVoById(String id) {
        return borrowInMapper.getVoById(id);
    }


    /**
     * 待入库单处理
     * @param type 1.新增单据 2作废单据
     * @param borrowInVo
     */
    private void processHouseWaitIn(int type, BorrowInVo borrowInVo) {
        if (type == 2) {
            HouseWaitIn houseWaitIn = new HouseWaitIn();
            houseWaitIn.setClose(true);
            houseWaitInMapper.update(houseWaitIn, new QueryWrapper<HouseWaitIn>().eq("borrow_in_id", borrowInVo.getId()));
            return ;
        }

        HouseWaitIn houseWaitIn = new HouseWaitIn();
        houseWaitIn.setId(UuidUtils.getUUID());
        houseWaitIn.setBorrowInId(borrowInVo.getId());
        houseWaitIn.setHouseId(borrowInVo.getHouseId());
        houseWaitIn.setClose(false);
        houseWaitIn.setStatus(1);//待入库
        houseWaitIn.setType(4);//设置类型为借入
        houseWaitIn.setTime(new Date());
        houseWaitIn.setCompanyId(borrowInVo.getCompanyId());
        houseWaitInMapper.insert(houseWaitIn);

        List<HouseWaitInGoods> houseWaitInGoodsList = new ArrayList<>();
        for (BorrowInGoodsVo vo : borrowInVo.getBorrowInGoodsVoList()) {
            HouseWaitInGoods houseWaitInGoods = new HouseWaitInGoods();
            houseWaitInGoods.setId(UuidUtils.getUUID());
            houseWaitInGoods.setHouseWaitInId(houseWaitIn.getId());
            houseWaitInGoods.setBorrowInGoodsId(vo.getId());
            houseWaitInGoods.setGoodsId(vo.getGoodsId());
            houseWaitInGoods.setHasInNumber(new BigDecimal("0"));
            houseWaitInGoods.setWaitInNumber(vo.getNumber());
            houseWaitInGoods.setNumber(vo.getNumber());
            houseWaitInGoods.setUnitId(vo.getUnitId());
            houseWaitInGoods.setTimes(vo.getTimes());
            houseWaitInGoods.setCompanyId(borrowInVo.getCompanyId());
            houseWaitInGoodsList.add(houseWaitInGoods);
        }
        houseWaitInGoodsMapper.insertBatch(houseWaitInGoodsList);
    }


    /**
     * 库存处理
     * @param type 1.新增单据 2作废单据
     * @param borrowInVo
     */
    private void processGoodsStock(int type, BorrowInVo borrowInVo){
        List<GoodsStock> goodsStockList = new ArrayList<>();
        for (BorrowInGoodsVo vo : borrowInVo.getBorrowInGoodsVoList()) {
            BigDecimal number = vo.getNumber().multiply(vo.getTimes());
            if (type == 2) {
                number = new BigDecimal("-"+number.toString());
            }
            //库存
            GoodsStock goodsStock = new GoodsStock();
            goodsStock.setId(UuidUtils.getUUID());
            goodsStock.setGoodsId(vo.getGoodsId());
            goodsStock.setHouseId(borrowInVo.getHouseId());
            goodsStock.setNum(number); //数量*换算倍数
            goodsStock.setTime(new Date());
            goodsStock.setCompanyId(borrowInVo.getCompanyId());
            goodsStockList.add(goodsStock);
        }

        goodsStockMapper.insertBatch(goodsStockList);
    }
}
